package com.link.base.base.expenseapplication.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.link.base.base.approval.model.Flow;
import com.link.base.base.approval.service.FlowService;
import com.link.base.base.expenseapplication.dao.mybatis.mapper.ApplicationHeadMapper;
import com.link.base.base.expenseapplication.dao.mybatis.mapper.ApplicationStoreMapper;
import com.link.base.base.expenseapplication.model.ApplicationHead;
import com.link.base.base.expenseapplication.model.ApplicationHeadInfo;
import com.link.base.base.expenseapplication.model.ApplicationStore;
import com.link.base.base.expenseapplication.model.ApplicationStoreDTO;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.util.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 费用申请头-费用申请头
 *
 * @author 黄正杨
 * @date 2019/04/16 19:06
 */
@Service
public class ApplicationHeadServiceImpl extends BasicServiceImpl<ApplicationHead> implements ApplicationHeadService {

    @Resource
    private ApplicationHeadMapper applicationHeadMapper;

    @Resource
    private ApplicationStoreMapper applicationStoreMapper;

    @Resource
    private ApplicationStoreService applicationStoreService;

    @Resource
    private FlowService flowService;

    @Override
    public BasicMapper<ApplicationHead> getBasicMapper() {
        return applicationHeadMapper;
    }

    /**
     * 查询费用申请头，并计算汇总金额
     *
     * @author 朱泊阳
     * @date 2019/04/18
     * @param entity
     * @return List
     * @throws Exception
     */
    @Override
    public List<ApplicationHead> queryByExamplePage(ApplicationHead entity) throws Exception {
        List<ApplicationHead> list = super.queryByExamplePage(entity);
        if (CollectionUtils.isEmpty(list)) {
            return list;
        }
        List<Long> ids = new ArrayList<>();
        list.forEach(item -> ids.add(item.getId()));
        Map<Long, ApplicationHead> computeMoneyMap = computeMoneyMap(ids);
        ApplicationHead applicationHead;
        for (ApplicationHead item : list) {
            applicationHead = computeMoneyMap.get(item.getId());
            if (null == applicationHead) {
                continue;
            }
            item.setCompanyAmount(applicationHead.getCompanyAmount());
            item.setTotalAmount(applicationHead.getTotalAmount());
            item.setAccountAmount(applicationHead.getAccountAmount());
        }
        return list;
    }

    /**
     * 查询费用申请头，并计算汇总金额
     *
     * @author 朱泊阳
     * @date 2019/04/18
     * @param entity
     * @return List
     * @throws Exception
     */
    @Override
    public ApplicationHead queryById(ApplicationHead entity) throws Exception {
        List<Long> ids = new ArrayList<>();
        ApplicationHead item = super.queryById(entity);
        if (null != item) {
            ids.add(item.getId());
            Map<Long, ApplicationHead> computeMoneyMap = computeMoneyMap(ids);
            ApplicationHead applicationHead = computeMoneyMap.get(item.getId());
            item.setCompanyAmount(applicationHead.getCompanyAmount());
            item.setTotalAmount(applicationHead.getTotalAmount());
            item.setAccountAmount(applicationHead.getAccountAmount());
            return item;
        } else {
            return item;
        }
    }

    /**
     * 根据费用申请的ID计算所有相关门店的汇总金额到费用申请头的金额汇总字段
     *
     * @author 朱泊阳
     * @date 2019/04/18
     * @param ids
     * @return Map
     * @throws Exception
     */
    @Override
    public Map<Long, ApplicationHead> computeMoneyMap(List<Long> ids) throws Exception {
        Map<Long, ApplicationHead> map = new HashMap<>();
        if (CollectionUtils.isEmpty(ids)) {
            return map;
        }
        ApplicationHead applicationHead;
        for (Long str : ids) {
            //初始化头对象，并放进map里方便后面汇总
            applicationHead = new ApplicationHead();
            applicationHead.setId(str);
            applicationHead.setTotalAmount(BigDecimal.ZERO);
            applicationHead.setCompanyAmount(BigDecimal.ZERO);
            applicationHead.setAccountAmount(BigDecimal.ZERO);
            map.put(str, applicationHead);
        }
        List<ApplicationStoreDTO> applicationStoreDTOS =  computeStroeMoneyMap(ids);
        if (CollectionUtils.isEmpty(applicationStoreDTOS)) {
            return map;
        }
        BigDecimal totalAmount;//申请总额
        BigDecimal accountAmount;//经销商承担金额
        BigDecimal companyAmount;//公司支持金额
        for (ApplicationStoreDTO temp : applicationStoreDTOS) {
            applicationHead = map.get(temp.getApplicationId());
            accountAmount = null == temp.getAccountAmount() ? BigDecimal.ZERO : temp.getAccountAmount();
            totalAmount = null == temp.getTotalAmount() ? BigDecimal.ZERO : temp.getTotalAmount();
            companyAmount = null == temp.getCompanyAmount() ? BigDecimal.ZERO : temp.getCompanyAmount();
            //汇总金额
            applicationHead.setTotalAmount(totalAmount.add(applicationHead.getTotalAmount()));
            applicationHead.setAccountAmount(accountAmount.add(applicationHead.getAccountAmount()));
            applicationHead.setCompanyAmount(companyAmount.add(applicationHead.getCompanyAmount()));
            map.put(applicationHead.getId(), applicationHead);
        }
        return map;
    }

    /**
     * 根据费用申请-门店的ID计算所有相关产品的汇总金额到门店的汇总金额字段
     *
     * @author 朱泊阳
     * @date 2019/04/18
     * @param ids
     * @return List
     * @throws Exception
     */
    @Override
    public List<ApplicationStoreDTO> computeStroeMoneyMap(List<Long> ids) throws Exception {
        //根据申请头id获取门店信息
        List<ApplicationStoreDTO> dtos = applicationStoreMapper.queryByApplicationIds(ids);
        Map<Long, ApplicationStoreDTO> map = new HashMap<>();
        if (CollectionUtils.isEmpty(dtos)) {
            return dtos;
        }
        List<Long> dtosIds = new ArrayList<>();
        dtos.forEach(item -> dtosIds.add(item.getId()));
        //执行根据费用申请-门店的ID计算他的金额汇总字段
        Map<Long, ApplicationStore> computeMoneyMap = applicationStoreService.computeMoneyMap(dtosIds);
        ApplicationStore applicationStore;
        for (ApplicationStoreDTO item : dtos) {
            applicationStore = computeMoneyMap.get(item.getId());
            if (null == applicationStore) {
                continue;
            }
            //汇总金额
            item.setCompanyAmount(applicationStore.getCompanyAmount());
            item.setTotalAmount(applicationStore.getTotalAmount());
            item.setAccountAmount(applicationStore.getAccountAmount());
        }
        return dtos;
    }

    @Override
    public void submit(ApplicationHead applicationHead, String applicationHeadDetail) throws Exception {
        Long selectUserId = null;
        String approvalType = "ExpenseApplication";
        //创建审批流程
        flowService.createFlow(applicationHead.getId(), approvalType, selectUserId,
                applicationHead.getApplicantAccountName(), applicationHead.getApplicantAccountId(), applicationHeadDetail);
        applicationHead.setStatus("Approvaling");
        applicationHeadMapper.update(applicationHead);
    }

    /**
     * 审批通过后更新客户信息及申请信息状态
     *
     * @param objectId
     * @param param1
     * @param param2
     * @param param3
     * @param param4
     * @param param5
     * @throws Exception
     */
    @Override
    public void applicationStatusUpdate(Long objectId, String param1, String param2, String param3, String param4, String param5) throws Exception {
        /*申请信息*/
        String approved = "Approved";
        String refuse = "Rejected";
        ApplicationHead applicationHead = new ApplicationHead();
        applicationHead.setId(objectId);
        ApplicationHead entity = queryById(applicationHead);
        //审批拒绝
        if (refuse.equals(param1)) {
            //已拒绝
            entity.setStatus(param2);
            applicationHeadMapper.update(entity);
        }
        //审批通过
        if (approved.equals(param1)) {
            //审核中
            entity.setStatus(param2);
            applicationHeadMapper.update(entity);
        }
    }

    /**
     * 审批处理-审批成功后更新信息
     *
     * @param entity
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void applicationObjectUpdate(ApplicationHeadInfo entity) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        Flow flow = new Flow();
        flow.setId(entity.getApprovalId());
        Flow flowObj = flowService.queryById(flow);

        String flag = "Y";
        if (flag.equals(flowObj.getCurrentIsWrite())) {
            /*审批详情封装json字符串*/
            String approvalDetail = mapper.writeValueAsString(entity);
            /*审批流程更新*/
            flowObj.setFlowObjDetail(approvalDetail);
            flowService.update(flowObj);
        }
        if (StringUtils.isBlank(flowObj.getNewStepNum())) {
            /*信息更新*/
            ApplicationHead applicationHead = entity.getApplicationHead();
            getBasicMapper().update(applicationHead);

        }
    }
}

